
# ifndef __DFX_MATRIX4_H__
# define __DFX_MATRIX4_H__

# include "dfxVector3.h"
# include "dfxVector4.h"

namespace DFX
{
    class DFX_EXPORT Matrix4
    {
    public:

        union
        {
            Float32 M1[16];
            Float32 M2[4][4];
        };

        Matrix4();
        Matrix4(const Matrix4 &m);

        Matrix4(Float32 m00, Float32 m01, Float32 m02, Float32 m03,
            Float32 m10, Float32 m11, Float32 m12, Float32 m13,
            Float32 m20, Float32 m21, Float32 m22, Float32 m23,
            Float32 m30, Float32 m31, Float32 m32, Float32 m33);

        inline void SetIdentity();

        inline Float32 GetDeterminant() const;
        inline Matrix4 GetTranspose() const;
        inline Matrix4 GetInverse() const;

        inline Vector3 TransformVector3(const Vector3 &v) const;
        inline Vector3 InvTransformVector3(const Vector3 &v) const;
        inline Vector3 TransformNormalVector3(const Vector3 &v) const;

        inline Vector4 TransformVector4(const Vector4 &v) const;
        inline Vector4 InvTransformVector4(const Vector4 &v) const;

        inline Matrix4 operator * (const Matrix4 &m) const;
        inline Matrix4& operator *= (const Matrix4 &m);

        inline Matrix4 Translate(const Vector3 &v);
        inline Matrix4 Scale(const Vector3 &v);
        inline Matrix4 Rotate(const Vector3 &v, Float32 a);

        static Matrix4 CreatePerspective(Float32 fov, Float32 aspect,
            Float32 minZ, Float32 maxZ);

        static Matrix4 CreateOrthogonal(Float32 left, Float32 top, Float32 right,
            Float32 bottom, Float32 nearZ, Float32 farZ);

        static Matrix4 CreateLookAt(const Vector3 &eye, const Vector3 &target, 
            const Vector3 &up);
    };
}

# endif